/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';
import { useDeepCompareEffect } from 'ahooks';
import { t } from 'i18next';
import { EditorState, LexicalEditor } from 'lexical';
import { useState, useTransition } from 'react';

import { SvgIcon } from '@/components/icon';
import { getNanoid } from '@/pages/chat/tools/tools';

import styles from './index.module.scss';
import FocusPlugin from './plugins/FocusPlugin';
import { MaxLengthPlugin } from './plugins/MaxLengthPlugin';
import OnBlurPlugin from './plugins/OnBlurPlugin';
import VariableLabelPickerPlugin from './plugins/VariableLabelPickerPlugin';
import VariableLabelPlugin from './plugins/VariableLabelPlugin';
import { VariableLabelNode } from './plugins/VariableLabelPlugin/node';
import VariablePickerPlugin from './plugins/VariablePickerPlugin';
import VariablePlugin from './plugins/VariablePlugin';
import { VariableNode } from './plugins/VariablePlugin/node';
import { EditorVariableLabelPickerType, EditorVariablePickerType } from './type';
import { textToEditorState } from './utils';

export default function Editor({
  minH = 200,
  maxH = 400,
  maxLength,
  showOpenModal = true,
  onOpenModal,
  variables,
  variableLabels,
  onChange,
  onBlur,
  value,
  placeholder = '',
  bg = 'white',
  tip = t('textarea_variable_picker_tip'),
}: {
  minH?: number;
  maxH?: number;
  maxLength?: number;
  showOpenModal?: boolean;
  onOpenModal?: () => void;
  variables: EditorVariablePickerType[];
  variableLabels: EditorVariableLabelPickerType[];
  onChange?: (editorState: EditorState, editor: LexicalEditor) => void;
  onBlur?: (editor: LexicalEditor) => void;
  value?: string;
  placeholder?: string;
  bg?: string;
  tip?: string;
}) {
  const [key, setKey] = useState(getNanoid(6));
  // const [refreshKey, setRefreshKey] = useState(0)
  const [_, startSts] = useTransition();
  const [focus, setFocus] = useState(false);
  const [scrollHeight, setScrollHeight] = useState(0);

  const initialConfig = {
    namespace: 'promptEditor',
    nodes: [VariableNode, VariableLabelNode],
    editorState: textToEditorState(value),
    onError: (error: Error) => {
      throw error;
    },
  };

  useDeepCompareEffect(() => {
    if (focus) return;
    setKey(getNanoid(6));
  }, [value, variables, variableLabels]);

  return (
    <div
      className="nodrag relative w-full cursor-text rounded-3xl text-gray-700"
      style={{ background: focus ? 'transparent' : bg }}
    >
      <LexicalComposer initialConfig={initialConfig} key={key}>
        <PlainTextPlugin
          contentEditable={
            <ContentEditable
              className={styles.contentEditable}
              style={{
                minHeight: `${minH}px`,
                maxHeight: `${maxH}px`,
              }}
            />
          }
          placeholder={
            <div className="pointer-events-none absolute bottom-0 left-0 right-0 top-0 rounded-md px-4 py-3">
              <div className="color-gray-400 w-full select-none whitespace-pre-wrap break-all text-xs">
                {`${tip}${tip ? '\n' : ''}${placeholder}`}
              </div>
            </div>
          }
          ErrorBoundary={LexicalErrorBoundary}
        />
        <HistoryPlugin />
        <MaxLengthPlugin maxLength={maxLength || 999999} />
        <FocusPlugin focus={focus} setFocus={setFocus} />
        <OnChangePlugin
          onChange={(editorState, editor) => {
            const rootElement = editor.getRootElement();
            setScrollHeight(rootElement?.scrollHeight || 0);
            startSts(() => {
              onChange?.(editorState, editor);
            });
          }}
        />
        <VariableLabelPlugin variables={variableLabels} />
        <VariablePlugin variables={variables} />
        <VariableLabelPickerPlugin variables={variableLabels} isFocus={focus} />
        <VariablePickerPlugin variables={variableLabels.length > 0 ? [] : variables} />
        <OnBlurPlugin onBlur={onBlur} />
      </LexicalComposer>
      {showOpenModal && (
        <div className="absolute bottom-1 right-2 z-10 cursor-pointer" onClick={onOpenModal}>
          {/* <FullscreenOutlined /> */}
          <SvgIcon icon="fullscreen" />
        </div>
      )}
    </div>
  );
}
